package boot.spring.service.impl;

import boot.spring.mapper.LeaveApplyMapper;
import boot.spring.po.LeaveApply;
import boot.spring.service.LeaveService;
import com.github.pagehelper.PageHelper;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 5)
@Service
public class LeaveServiceImpl implements LeaveService {

    @Resource
    private LeaveApplyMapper leaveApplyMapper;
    @Resource
    private IdentityService identityService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private TaskService taskService;


    public ProcessInstance startWorkflow(LeaveApply apply, String userId, Map<String, Object> variables) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        apply.setApply_time(sdf.format(new Date()));
        apply.setUser_id(userId);
        leaveApplyMapper.save(apply);
        //使用leaveApply表的主键作为businessKey,连接业务数据和流程数据
        String businessKey = String.valueOf(apply.getId());
        identityService.setAuthenticatedUserId(userId);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave", businessKey, variables);
        String instanceId = processInstance.getId();
        apply.setProcess_instance_id(instanceId);
        leaveApplyMapper.updateByPrimaryKey(apply);
        return processInstance;
    }

    public List<LeaveApply> getPageDeptTask(String username, int firstRow, int rowCount) {
        List<LeaveApply> results = new ArrayList<>();
        // 使用任务候选人查询待办列表
        List<Task> tasks = taskService.createTaskQuery().taskAssignee(username).taskName("部门领导审批").listPage(firstRow, rowCount);
        for (Task task : tasks) {
            String instanceId = task.getProcessInstanceId();
            ProcessInstance ins = runtimeService.createProcessInstanceQuery().processInstanceId(instanceId).singleResult();
            String businessKey = ins.getBusinessKey();
            // 使用业务号查出业务数据一起返回
            LeaveApply a = leaveApplyMapper.getLeaveApply(Integer.parseInt(businessKey));
            a.setTask(task);
            results.add(a);
        }
        return results;
    }

    public int getAllDeptTask(String username) {
        List<Task> tasks = taskService.createTaskQuery().taskAssignee(username).taskName("部门领导审批").list();
        return tasks.size();
    }

    public LeaveApply getleave(int id) {
        return leaveApplyMapper.getLeaveApply(id);
    }

    public List<LeaveApply> getPageHrTask(String username, int firstRow, int rowCount) {
        List<LeaveApply> results = new ArrayList<>();
        List<Task> taskList = taskService.createTaskQuery().taskAssignee(username).taskName("人事审批").listPage(firstRow, rowCount);
        for (Task task : taskList) {
            String processInstanceId = task.getProcessInstanceId();
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            String businessKey = processInstance.getBusinessKey();
            LeaveApply leaveApply = leaveApplyMapper.getLeaveApply(Integer.parseInt(businessKey));
            leaveApply.setTask(task);
            results.add(leaveApply);
        }
        return results;
    }

    public int getallhrtask(String username) {
        List<Task> tasks = taskService.createTaskQuery().taskAssignee(username).taskName("人事审批").list();
        return tasks.size();
    }

    public List<LeaveApply> getpageXJtask(String userid, int firstrow, int rowcount) {
        List<LeaveApply> results = new ArrayList<>();
        List<Task> tasks = taskService.createTaskQuery().taskCandidateOrAssigned(userid).taskName("销假").listPage(firstrow, rowcount);
        for (Task task : tasks) {
            String instanceid = task.getProcessInstanceId();
            ProcessInstance ins = runtimeService.createProcessInstanceQuery().processInstanceId(instanceid).singleResult();
            String businesskey = ins.getBusinessKey();
            LeaveApply a = leaveApplyMapper.getLeaveApply(Integer.parseInt(businesskey));
            a.setTask(task);
            results.add(a);
        }
        return results;
    }

    public int getallXJtask(String userid) {
        List<Task> tasks = taskService.createTaskQuery().taskCandidateOrAssigned(userid).taskName("销假").list();
        return tasks.size();
    }

    public List<LeaveApply> getpageupdateapplytask(String userid, int firstrow, int rowcount) {
        List<LeaveApply> results = new ArrayList<>();
        List<Task> tasks = taskService.createTaskQuery().taskCandidateOrAssigned(userid).taskName("调整申请").listPage(firstrow, rowcount);
        for (Task task : tasks) {
            String instanceid = task.getProcessInstanceId();
            ProcessInstance ins = runtimeService.createProcessInstanceQuery().processInstanceId(instanceid).singleResult();
            String businesskey = ins.getBusinessKey();
            LeaveApply a = leaveApplyMapper.getLeaveApply(Integer.parseInt(businesskey));
            a.setTask(task);
            results.add(a);
        }
        return results;
    }

    public int getallupdateapplytask(String userid) {
        List<Task> tasks = taskService.createTaskQuery().taskCandidateOrAssigned(userid).taskName("调整申请").list();
        return tasks.size();
    }

    public void completeReportBack(String taskId, String realStartTime, String realEndTime) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        String instanceId = task.getProcessInstanceId();
        ProcessInstance ins = runtimeService.createProcessInstanceQuery().processInstanceId(instanceId).singleResult();
        String businessKey = ins.getBusinessKey();
        LeaveApply a = leaveApplyMapper.getLeaveApply(Integer.parseInt(businessKey));
        a.setReality_start_time(realStartTime);
        a.setReality_end_time(realEndTime);
        leaveApplyMapper.updateByPrimaryKey(a);
        taskService.complete(taskId);
    }

    public void updateComplete(String taskId, LeaveApply leave, String reapply) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        String processInstanceId = task.getProcessInstanceId();
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        String businessKey = processInstance.getBusinessKey();
        LeaveApply leaveApply = leaveApplyMapper.getLeaveApply(Integer.parseInt(businessKey));
        leaveApply.setLeave_type(leave.getLeave_type());
        leaveApply.setStart_time(leave.getStart_time());
        leaveApply.setEnd_time(leave.getEnd_time());
        leaveApply.setReason(leave.getReason());
        Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("reapply", reapply);
        if (reapply.equals("true")) {
            leaveApplyMapper.updateByPrimaryKey(leaveApply);
            taskService.complete(taskId, variables);
        } else
            taskService.complete(taskId, variables);
    }

    public List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinitionEntity, List<HistoricActivityInstance> activityInstances) {
        List<String> highFlows = new ArrayList<>();
        // 用以保存高亮的线flowId
//        for (int i = 0; i < activityInstances.size(); i++) {
//            // 对历史流程节点进行遍历
//            List<String> activeActivityIds = runtimeservice.getActiveActivityIds(activityInstances.get(i).getActivityId());
//
//            ActivityImpl activityImpl = processDefinitionEntity.findActivity(activityInstances.get(i).getActivityId());// 得 到节点定义的详细信息
//            List<ActivityImpl> sameStartTimeNodes = new ArrayList<ActivityImpl>();// 用以保存后需开始时间相同的节点
//            if ((i + 1) >= activityInstances.size()) {
//                break;
//            }
//            ActivityImpl sameActivityImpl1 = processDefinitionEntity.findActivity(activityInstances.get(i + 1).getActivityId());// 将后面第一个节点放在时间相同节点的集合里
//            sameStartTimeNodes.add(sameActivityImpl1);
//            for (int j = i + 1; j < activityInstances.size() - 1; j++) {
//                HistoricActivityInstance activityImpl1 = activityInstances
//                        .get(j);// 后续第一个节点
//                HistoricActivityInstance activityImpl2 = activityInstances
//                        .get(j + 1);// 后续第二个节点
//                if (activityImpl1.getStartTime().equals(
//                        activityImpl2.getStartTime())) {// 如果第一个节点和第二个节点开始时间相同保存
//                    ActivityImpl activity = processDefinitionEntity
//                            .findActivity(activityImpl2.getActivityId());
//                    sameStartTimeNodes.add(activity);
//                } else {// 有不相同跳出循环
//                    break;
//                }
//            }
//            List<PvmTransition> pvmTransitions = activityImpl.getOutgoingTransitions();// 取出节点的所有出去的线
//            for (PvmTransition pvmTransition : pvmTransitions) {// 对所有的线进行遍历
//                ActivityImpl pvmActivityImpl = (ActivityImpl) pvmTransition.getDestination();// 如果取出的线的目标节点存在时间相同的节点里，保存该线的id，进行高亮显示
//                if (sameStartTimeNodes.contains(pvmActivityImpl)) {
//                    highFlows.add(pvmTransition.getId());
//                }
//            }
//        }
        return highFlows;
    }

    @Override
    public List<LeaveApply> getPageByApplyer(String username, int current, int rowCount) {
        PageHelper.startPage(current, rowCount);
        return leaveApplyMapper.listLeaveApplyByApplyer(username);
    }

    @Override
    public int getAllByApplyer(String username) {
        return leaveApplyMapper.listLeaveApplyByApplyer(username).size();
    }
}
